#include "kstdio.h"
#include "astralapi.h"

static char sbf_system_in[512];

static int exec_full(SysBuffer sbf);
static int exec_empty(SysBuffer sbf);

static struct SysBuffer global_stdin =
{
    .buff = sbf_system_in,
    .ptr = 0,
    .size = 512,
    .full_handle = CAST_AS(runable, exec_full),
    .empty_handle = CAST_AS(runable, exec_empty),
};

static int exec_full(SysBuffer sbf)
{
    return 0;
}

static int exec_empty(SysBuffer sbf)
{
    int actual;
    static AstralDevice dev = NULL;
    if (!dev)
    {
        dev = open_device("tty0");
        if (!dev)
        {
            return 0;
        }
    }
    dev->operations->dread(dev, sbf->buff, sbf->size, &actual);
    return actual;
}

// void read_from_kstdin(const char *buff, int size, int *actual)


static boolean is_showable(char c)
{
    return (31 < c) && (c <127);
}

char getc_from_kstdin()
{
    static int putted = 0;
    char c = getc_buffer(&global_stdin);
    switch (c)
    {
    case '\n':
    case '\r':
        putc_to_kstdout('\n');
        putc_to_kstdout('\r');
        putted = 0;
        break;
    case 8: // backspace
    case 127: // DEL
        if (putted)
        {
            putc_to_kstdout('\b');
            putc_to_kstdout(' ');
            putc_to_kstdout('\b');
            putted--;
        }
        else
        {
            putc_to_kstdout('\007');
        }
        break;
    case 9: // Tab
    default:
        if(is_showable(c))
        {
            putc_to_kstdout(c);
            putted++;
        }
        break;
    }

    return c;
}